package com.leyantech.ecp.agenx.task.di;

import com.leyantech.ai.DialogueReply;
import com.leyantech.ecp.agenx.task.filter.TaskFilter;
import com.leyantech.ecp.agenx.task.filter.takeaction.TakeActionAssistantOnlineFilter;
import com.leyantech.ecp.agenx.task.filter.takeaction.TakeActionFilter;
import com.leyantech.ecp.agenx.task.filter.takeaction.TakeActionRateLimiter;
import com.leyantech.ecp.agenx.task.filter.task.TaskMessageFilter;
import com.leyantech.ecp.agenx.task.filter.task.TaskMessageRateLimiter;

import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import io.vertx.core.json.JsonObject;

import java.util.stream.Stream;

/**
 * @author eahau, {@literal <eahau@foxmail.com>}
 * @date 2022-11-16.
 */
public class FilterModule extends AbstractModule {

  @Override
  protected void configure() {
//    final List<Class<? extends TaskFilter>> taskClassList = new Reflections(
//        TaskFilter.class.getPackage().getName())
//        .getSubTypesOf(TaskFilter.class)
//        .stream()
//        .filter(clz -> !Modifier.isAbstract(clz.getModifiers()))
//        .collect(Collectors.toList());
//
//    // 确保 RateLimiter 在最后执行
//    final List<Class<? extends TaskFilter>> rateLimiterClassList = taskClassList.stream()
//        .filter(RateLimiter.class::isAssignableFrom)
//        .collect(Collectors.toList());
//
//    taskClassList.removeIf(RateLimiter.class::isAssignableFrom);
//    taskClassList.addAll(rateLimiterClassList);
//
//    Stream.of(
//        Pair.of("task", new TypeLiteral<TaskFilter<JsonObject>>() {
//        }), Pair.of("takeaction", new TypeLiteral<TaskFilter<DialogueReply>>() {
//        })
//    )
//        .forEach(pair -> {
//          final String packageLastName = pair.getKey();
//          final Multibinder<? extends TaskFilter<?>> multiBinder = Multibinder
//              .newSetBinder(binder(), pair.getRight());
//          taskClassList
//              .stream()
//              .filter(clz -> clz.getPackage().getName().endsWith(packageLastName))
//              .map(clz -> (Class) clz)
//              .forEach(clz -> multiBinder.addBinding().to(clz).asEagerSingleton());
//        });
  }

  @Singleton
  @Provides
  public ImmutableList<TaskFilter<JsonObject>> provideTaskFilters(Injector injector) {
    return Stream.of(TaskMessageFilter.class, TaskMessageRateLimiter.class)
        .map(injector::getInstance)
        .collect(ImmutableList.toImmutableList());
  }

  @Singleton
  @Provides
  public ImmutableList<TaskFilter<DialogueReply>> provideTakeActionFilters(Injector injector) {
    return Stream.of(
        TakeActionFilter.class,
        TakeActionAssistantOnlineFilter.class,
        TakeActionRateLimiter.class
    )
        .map(injector::getInstance)
        .collect(ImmutableList.toImmutableList());
  }

}
